package com.yichuang.wuziqi.game;

import android.graphics.Point;
import android.util.Log;

import com.yichuang.wuziqi.domain.Data;
import com.yichuang.wuziqi.player.Player;
import com.yichuang.wuziqi.tool.JsonTools;

import java.util.Random;

/**
 * Created by xcm on 17-12-3.
 */

public abstract class Game implements IGame, Runnable {

    public static final String TAG = "xcm";

    public static final int MAX_LINE = 13;

    public static final int GAME_STATUS_STARTED = 0;
    public static final int GAME_STATUS_END = 1;

    private Player[] players = new Player[2];
    int turn = new Random().nextInt(2);

    private boolean isGameOver = false;
    private Recorder recorder;
    private GameListener gameListener;

    public Game(){

    }

    public Game(Player whitePlayer, Player blackPlayer) {
        setPlayer(whitePlayer, blackPlayer);
    }

    @Override
    public boolean save() {
        return false;
    }

    @Override
    public void setRecorder(Recorder recorder) {
        this.recorder = recorder;
    }

    public void setGameListener(GameListener gameListener) {
        this.gameListener = gameListener;
    }

    public void setGameOver(boolean isGameOver) {
        this.isGameOver = isGameOver;
    }

    public void setPlayer(Player whitePlayer, Player blackPlayer) {
        players[0] = whitePlayer;
        players[1] = blackPlayer;
    }

    public Player getCurrentPlayer() {
        return players[getCurrentPlayerTurn()];
    }

    public Player getOppositePlayer() {
        return players[getOppositePlayerTurn()];
    }

    private int getCurrentPlayerTurn() {
        return turn % 2;
    }

    private int getOppositePlayerTurn() {
        return (turn + 1) % 2;
    }

    @Override
    public void run() {

        Player currentPlayer = getCurrentPlayer();
        Log.d(TAG, "run: " + currentPlayer.getSide());

        //通知双方游戏开始
        Data data = currentPlayer.oneStep(new Data(Data.ServerAction.GAME_START, Player.WHITE_SIDE + ""));
        getOppositePlayer().oneStep(new Data(Data.ServerAction.GAME_START, Player.BLACK_SIDE + ""));
        if (gameListener != null) {
            gameListener.onGameStatusChanged(Game.GAME_STATUS_STARTED);
        }

        while (!isGameOver) {
            //切换选手
            turn++;
            currentPlayer = getCurrentPlayer();
            switch (data.getType()) {
                case Data.PlayerAction.PLAYER_DROP:
                    Point p = JsonTools.toOject(data.getData(), Point.class);
                    //记录上一个选手的下棋结果
                    recorder.record(players[(turn + 1) % 2].getSide(), p);
                    if (gameListener != null) {
                        gameListener.onDrop(getCurrentPlayerTurn(), p);
                    }
                    if (recorder.checkGameOver()) {
                        //游戏结束,当前用户失败
                        isGameOver = true;
                        getOppositePlayer().oneStep(new Data(Data.ServerAction.GAME_OVER, "1"));
                        currentPlayer.oneStep(new Data(Data.ServerAction.GAME_OVER, "0"));
                        if (gameListener != null) {
                            gameListener.onGameStatusChanged(Game.GAME_STATUS_END);
                        }
                        return;
                    }
                    break;
                case Data.PlayerAction.PLAYER_ADMIT_BEATEN:
                    //认输,当前用户获胜
                    isGameOver = true;
                    currentPlayer.oneStep(new Data(Data.ServerAction.GAME_OVER, "1"));
                    getOppositePlayer().oneStep(new Data(Data.ServerAction.GAME_OVER, "0"));
                    if (gameListener != null) {
                        gameListener.onGameStatusChanged(Game.GAME_STATUS_END);
                    }
                    return;
            }
            data = currentPlayer.oneStep(data);
            Log.d(TAG, "run: " + currentPlayer.getSide());
        }
    }

    public void takeBack() {
        recorder.takeBack(turn % 2);
        turn--;
        isGameOver = false;
    }

    public interface GameListener {
        void onDrop(int who, Point position);

        void onGameStatusChanged(int status);
    }
}